﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Architecture.Linq;
using System.Data.Linq.SqlClient;
using System.ComponentModel;

namespace Emerald.Business.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    public class UserController : GenericController<User, EmeraldDataContext>
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        [DataObjectMethod(DataObjectMethodType.Select)]
        public User GetUserByUsername(string username)
        {
            #region Validation
            if (String.IsNullOrEmpty(username))
            {
                throw new ArgumentNullException("username");
            }
            #endregion

            User result = (from user in EntityTable
                           where user.Username == username
                           select user).SingleOrDefault();

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        [DataObjectMethod(DataObjectMethodType.Select)]
        public User GetUserByEmail(string email)
        {
            #region Validation
            if (String.IsNullOrEmpty(email))
            {
                throw new ArgumentNullException("email");
            }
            #endregion

            User result = (from user in EntityTable
                           where user.Email == email
                           select user).SingleOrDefault();

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="emailToMatch"></param>
        /// <param name="maximumRows"></param>
        /// <param name="startRowIndex"></param>
        /// <returns></returns>
        [DataObjectMethod(DataObjectMethodType.Select)]
        public IQueryable<User> FindUsersByEmail(string emailToMatch, int maximumRows, int startRowIndex)
        {
            #region Validation
            if (maximumRows <= 0)
            {
                throw new ArgumentOutOfRangeException("maximumRows");
            }

            if (startRowIndex < 0)
            {
                throw new ArgumentOutOfRangeException("startRowIndex");
            }
            #endregion

            IQueryable<User> result = from user in EntityTable
                                      where SqlMethods.Like(user.Email, PrepareForCompare(emailToMatch))
                                      select user;

            return result.Skip(startRowIndex).Take(maximumRows);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="usernameToMatch"></param>
        /// <param name="maximumRows"></param>
        /// <param name="startRowIndex"></param>
        /// <returns></returns>
        [DataObjectMethod(DataObjectMethodType.Select)]
        public IQueryable<User> FindUsersByName(string usernameToMatch, int maximumRows, int startRowIndex)
        {
            #region Validation
            if (maximumRows <= 0)
            {
                throw new ArgumentOutOfRangeException("maximumRows");
            }

            if (startRowIndex < 0)
            {
                throw new ArgumentOutOfRangeException("startRowIndex");
            }
            #endregion

            IQueryable<User> result = from user in EntityTable
                                      where SqlMethods.Like(user.Username, PrepareForCompare(usernameToMatch))
                                      select user;

            return result.Skip(startRowIndex).Take(maximumRows);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="compareTime"></param>
        /// <returns></returns>
        public int GetNumberOfUsersOnline(DateTime compareTime)
        {
            int result = EntityTable.Count(user => user.IsOnline);

            return result;
        }

        private string PrepareForCompare(string input)
        {
            return input.Replace('*', '%').Replace('?', '_');
        }
    }
}
